/*!
 * \file ctp_common.hpp
 * \project AI_CTP
 * 
 * \brief CTP通用数据结构和枚举定义 - 基于wt_ctp成功实现
 */
#pragma once

#include <string>
#include <vector>
#include <memory>
#include <functional>
#include <cstring>
#include <atomic>

// 使用CTP官方头文件 - 统一使用相对路径避免中文字符问题
#ifdef WIN32
    // Windows平台使用绝对路径
    #include "ThostFtdcMdApi.h"
    #include "ThostFtdcTraderApi.h"
    #include "ThostFtdcUserApiStruct.h"
    #include "ThostFtdcUserApiDataType.h"
#else
    // Linux平台
    #include "ThostFtdcMdApi.h"
    #include "ThostFtdcTraderApi.h"
    #include "ThostFtdcUserApiStruct.h"
    #include "ThostFtdcUserApiDataType.h"
#endif

namespace ctp_api {

// 连接状态枚举
enum class ConnectionState {
    DISCONNECTED = 0,
    CONNECTING,
    CONNECTED,
    LOGGED_IN,
    READY
};

// 行情状态枚举  
enum class MdState {
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    LOGGING_IN,
    LOGGED_IN,
    READY
};

// 交易状态枚举
enum class TradeState {
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    AUTHENTICATING,
    AUTHENTICATED,
    LOGGING_IN,
    LOGGED_IN,
    CONFIRMING,
    CONFIRMED,
    READY
};

// 简化的Tick数据结构（用于Python绑定）
struct TickInfo {
    std::string instrument_id;
    std::string trading_day;
    std::string update_time;
    std::string action_day;
    double last_price = 0.0;
    uint64_t volume = 0;
    double turnover = 0.0;
    uint64_t open_interest = 0;
    double bid_price1 = 0.0;
    int bid_volume1 = 0;
    double ask_price1 = 0.0;
    int ask_volume1 = 0;
    double open_price = 0.0;
    double high_price = 0.0;
    double low_price = 0.0;
    double pre_close_price = 0.0;
    double upper_limit_price = 0.0;
    double lower_limit_price = 0.0;
    
    TickInfo() = default;
};

// K线数据结构（用于Python绑定）
struct BarInfo {
    std::string instrument_id;
    std::string time_str;
    uint64_t bar_time = 0;
    int period = 0;
    double open = 0.0;
    double high = 0.0;
    double low = 0.0;
    double close = 0.0;
    uint64_t volume = 0;
    double turnover = 0.0;
    uint64_t open_interest = 0;
    
    BarInfo() = default;
};

// 错误信息
struct ErrorInfo {
    int error_id = 0;
    std::string error_msg;
    
    ErrorInfo() = default;
    ErrorInfo(int id, const std::string& msg) : error_id(id), error_msg(msg) {}
    
    bool is_error() const { return error_id != 0; }
};

// 登录结果信息
struct LoginInfo {
    std::string trading_day;
    std::string login_time;
    std::string broker_id;
    std::string user_id;
    std::string system_name;
    int front_id = 0;
    int session_id = 0;
    std::string max_order_ref;
    
    LoginInfo() = default;
};

// 深度行情数据
struct DepthMarketData {
    std::string trading_day;
    std::string instrument_id;
    std::string exchange_id;
    double last_price = 0.0;
    double pre_settlement_price = 0.0;
    double pre_close_price = 0.0;
    long long pre_open_interest = 0;
    double open_price = 0.0;
    double highest_price = 0.0;
    double lowest_price = 0.0;
    int volume = 0;
    double turnover = 0.0;
    long long open_interest = 0;
    double close_price = 0.0;
    double settlement_price = 0.0;
    double upper_limit_price = 0.0;
    double lower_limit_price = 0.0;
    std::string update_time;
    int update_millisec = 0;
    double bid_price1 = 0.0;
    int bid_volume1 = 0;
    double ask_price1 = 0.0;
    int ask_volume1 = 0;
    double average_price = 0.0;
    std::string action_day;
    
    DepthMarketData() = default;
};

// 订单信息结构
struct OrderInfo {
    std::string instrument_id;      // 合约代码
    std::string order_ref;          // 报单引用
    std::string order_sys_id;       // 系统编号
    char direction = 0;             // 买卖方向
    char offset_flag = 0;           // 开平标志
    double limit_price = 0.0;       // 价格
    int volume_total_original = 0;  // 数量
    int volume_traded = 0;          // 已成数量
    int volume_left = 0;            // 剩余数量
    char order_status = 0;          // 订单状态
    std::string status_msg;         // 状态信息
    std::string insert_time;        // 下单时间
    std::string update_time;        // 更新时间
    int front_id = 0;               // 前置编号
    int session_id = 0;             // 会话编号
    
    OrderInfo() = default;
};

// 成交信息结构
struct TradeInfo {
    std::string trade_id;          // 成交编号
    std::string order_ref;         // 报单引用
    std::string order_sys_id;      // 系统编号
    std::string instrument_id;     // 合约代码
    char direction = 0;            // 买卖方向
    char offset_flag = 0;          // 开平标志
    double price = 0.0;            // 成交价格
    int volume = 0;                // 成交数量
    std::string trade_time;        // 成交时间
    
    TradeInfo() = default;
};

// 持仓信息结构
struct PositionInfo {
    std::string instrument_id;     // 合约代码
    char pos_direction = 0;        // 持仓方向
    int position = 0;              // 总持仓
    int position_today = 0;        // 今仓
    int position_yesterday = 0;    // 昨仓
    double open_cost = 0.0;        // 开仓成本
    double position_cost = 0.0;    // 持仓成本
    double margin = 0.0;           // 保证金
    double profit = 0.0;           // 持仓盈亏
    
    PositionInfo() = default;
};

// 账户信息结构
struct AccountInfo {
    std::string account_id;        // 账户号
    double pre_balance = 0.0;      // 上次结算准备金
    double balance = 0.0;          // 账户余额
    double available = 0.0;        // 可用资金
    double margin = 0.0;           // 当前占用保证金
    double profit = 0.0;           // 当日盈亏
    double commission = 0.0;       // 手续费
    
    AccountInfo() = default;
};

// 订单请求结构
struct OrderRequest {
    std::string instrument_id;     // 合约代码
    char direction = '0';          // 买卖方向：'0'买，'1'卖
    char offset_flag = '0';        // 开平标志：'0'开仓，'1'平仓，'3'平今，'4'平昨
    double limit_price = 0.0;      // 限价
    int volume = 0;                // 数量
    char price_type = '2';         // 价格类型：'1'市价，'2'限价
    char time_condition = '3';     // 有效期类型：'1'立即完成否则撤销，'3'当日有效
    
    OrderRequest() = default;
};

// 撤单请求结构
struct CancelRequest {
    std::string order_ref;         // 报单引用
    std::string order_sys_id;      // 系统编号
    int front_id = 0;              // 前置编号
    int session_id = 0;            // 会话编号
    
    CancelRequest() = default;
};

// 工具函数
inline void safe_copy_string(char* dest, const std::string& src, size_t dest_size) {
    if (dest && dest_size > 0) {
        size_t copy_len = std::min(src.length(), dest_size - 1);
        memcpy(dest, src.c_str(), copy_len);
        dest[copy_len] = '\0';
    }
}

} // namespace ctp_api 